home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Joy 1: Lollypop
/
Joy #1: Lollypop.iso
/
viewer
/
unixview
/
xgiftar.z
/
xgiftar
/
merge.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-05-20
|
6KB
|
236 lines
/* merge.c:
*
* merge two images
*
* jim frost 09.27.89
*
* Copyright 1989, 1990, 1991 Jim Frost.
* See included file "copyright.h" for complete copyright information.
*/
#include "copyright.h"
#include "image.h"
/* if merging bitmaps they don't have to be converted to
* 24-bit. this saves a lot of space.
*/
static Image *bitmapToBitmap(src, dest, atx, aty, clipw, cliph, verbose)
Image *src, *dest;
unsigned int atx, aty, clipw, cliph;
unsigned int verbose;
{ unsigned int destlinelen, srclinelen;
unsigned int deststart;
unsigned int flip;
unsigned int x, y;
byte *destline, *srcline;
byte deststartmask;
byte destmask, srcmask;
byte *destpixel, *srcpixel;
destlinelen= (dest->width / 8) + (dest->width % 8 ? 1 : 0);
srclinelen= (src->width / 8) + (src->width % 8 ? 1 : 0);
destline= dest->data + (aty * destlinelen);
srcline= src->data;
deststart= atx / 8;
deststartmask= 0x80 >> (atx % 8);
flip= ((*dest->rgb.red == *(src->rgb.red + 1)) &&
(*dest->rgb.green == *(src->rgb.green + 1)) &&
(*dest->rgb.blue == *(src->rgb.blue + 1)));
for (y= 0; y < cliph; y++) {
destpixel= destline + deststart;
srcpixel= srcline;
destmask= deststartmask;
srcmask= 0x80;
for (x= 0; x < clipw; x++) {
if (flip)
if (*srcpixel & srcmask)
*destpixel &= ~destmask;
else
*destpixel |= destmask;
else
if (*srcpixel & srcmask)
*destpixel |= destmask;
else
*destpixel &= ~destmask;
destmask >>= 1;
srcmask >>= 1;
if (destmask == 0) {
destmask= 0x80;
destpixel++;
}
if (srcmask == 0) {
srcmask= 0x80;
srcpixel++;
}
}
destline += destlinelen;
srcline += srclinelen;
}
if (verbose)
printf("done\n");
return(dest);
}
static Image *anyToTrue(src, dest, atx, aty, clipw, cliph, verbose)
Image *src, *dest;
unsigned int atx, aty, clipw, cliph;
unsigned int verbose;
{ Pixel fg, bg;
unsigned int destlinelen, srclinelen;
unsigned int deststart;
unsigned int x, y;
byte *destline, *srcline;
byte *destpixel, *srcpixel;
byte srcmask;
Pixel pixval;
if (!TRUEP(dest))
dest= expand(dest);
switch (src->type) {
case IBITMAP:
fg= RGB_TO_TRUE(src->rgb.red[1], src->rgb.green[1], src->rgb.blue[1]);
bg= RGB_TO_TRUE(src->rgb.red[0], src->rgb.green[0], src->rgb.blue[0]);
destlinelen= dest->width * dest->pixlen;
srclinelen= (src->width / 8) + (src->width % 8 ? 1 : 0);
destline= dest->data + (aty * destlinelen);
srcline= src->data;
deststart= atx * dest->pixlen;
for (y= 0; y < cliph; y++) {
destpixel= destline + deststart;
srcpixel= srcline;
srcmask= 0x80;
for (x= 0; x < clipw; x++) {
valToMem((*srcpixel & srcmask ? fg : bg), destpixel, 3);
destpixel += 3;
srcmask >>= 1;
if (srcmask == 0) {
srcpixel++;
srcmask= 0x80;
}
}
destline += destlinelen;
srcline += srclinelen;
}
break;
case IRGB:
destlinelen= dest->width * dest->pixlen;
srclinelen= src->width * src->pixlen;
deststart= atx * dest->pixlen;
destline= dest->data + (aty * destlinelen);
srcline= src->data;
for (y= 0; y < cliph; y++) {
destpixel= destline + deststart;
srcpixel= srcline;
for (x= 0; x < clipw; x++) {
pixval= memToVal(srcpixel, src->pixlen);
*(destpixel++)= src->rgb.red[pixval] >> 8;
*(destpixel++)= src->rgb.green[pixval] >> 8;
*(destpixel++)= src->rgb.blue[pixval] >> 8;
srcpixel += src->pixlen;
}
destline += destlinelen;
srcline += srclinelen;
}
break;
case ITRUE:
destlinelen= dest->width * dest->pixlen;
srclinelen= src->width * src->pixlen;
deststart= atx * dest->pixlen;
destline= dest->data + (aty * destlinelen);
srcline= src->data;
for (y= 0; y < cliph; y++) {
destpixel= destline + deststart;
srcpixel= srcline;
for (x= 0; x < clipw; x++) {
*(destpixel++)= *(srcpixel++);
*(destpixel++)= *(srcpixel++);
*(destpixel++)= *(srcpixel++);
}
destline += destlinelen;
srcline += srclinelen;
}
break;
}
if (verbose)
printf("done\n");
return(dest);
}
/* put src image on dest image
*/
Image *merge(dest, src, atx, aty, verbose)
Image *dest;
Image *src;
int atx, aty;
unsigned int verbose;
{ int clipw, cliph;
int clipped = 0;
Image *newimage;
goodImage(dest, "merge");
goodImage(src, "merge");
if (verbose) {
printf(" Merging...");
fflush(stdout);
}
/* adjust clipping of src to fit within dest
*/
clipw= src->width;
cliph= src->height;
if ((atx + clipw < 0) || (aty + cliph < 0) ||
(atx >= (int)dest->width) ||
(aty >= (int)dest->height)) /* not on dest, ignore */
return;
if (atx + clipw > dest->width)
clipw = dest->width - atx;
if (aty + cliph > dest->height)
cliph = dest->height - aty;
/* extra clipping required for negative offsets
*/
if ( atx < 0 || aty < 0 ) {
int clipx, clipy;
if ( atx < 0 ) {
clipx = -atx;
clipw += atx;
atx = 0;
}
else
clipx = 0;
if ( aty < 0 ) {
clipy = -aty;
cliph += aty;
aty = 0;
}
else
clipy = 0;
clipped = 1;
src = clip(src, clipx, clipy, clipw, cliph, verbose);
}
if (BITMAPP(dest) && BITMAPP(src))
newimage= bitmapToBitmap(src, dest, (unsigned int)atx, (unsigned int)aty,
clipw, cliph, verbose);
else
newimage= anyToTrue(src, dest, (unsigned int)atx, (unsigned int)aty,
clipw, cliph, verbose);
if (clipped)
freeImage(src);
return(newimage);
}